#!/usr/bin/env python
# -*- coding: utf-8 -*-

from base64 import urlsafe_b64encode,urlsafe_b64decode
def u64enc(f):
    assert type(f)==unicode
    a=f.encode("utf_8")
    b=urlsafe_b64encode( a)
    return unicode(b,"utf_8")

def u64dec(f):
    assert type(f)==unicode
    a=f.encode("utf_8")
    b=urlsafe_b64decode( a)
    return unicode(b,"utf_8")

class OList:
    """
        l=[("martin","jean"),("dupond","yves"),("klein","michel")]
        or
        l=[["martin","jean"],["dupond","yves"],["klein","michel"]]

        ll = OList("nom","prenom")(l)
        print ll[2].prenom,"==",ll[2][1],"==",l[2][1]
    """
    def __init__(self,*a):
        self.__n=list(a)
    def __call__(self,liste):
        class NList(list):
            def __init__(self,n,l):
                assert len(l)==len(n), "No match "+str(n)+" and "+str(l)
                list.__init__(self,l)
                for i in n:
                    setattr(self,i,l[ n.index(i) ])
                self.__noms = n
            def __repr__(self):
                m=" ".join(["""%s='%s'""" % (i,str(getattr(self,i))) for i in self.__noms])
                return "<objet %s>" % m
        return [ NList(self.__n, i) for i in liste ]
import math

def mkPager(ll,nbperpage,page=None):
    """
    Fabrique un *pager*, en fonction de la list "ll", et du
    nb d'item à afficher par page "nbperpage".

    retourne un tuple contenant :
        - un tuple touches (first,prev,next,last) : contenant le num de page pour la navigation
             first et last sont toujours renseignés
             next et prev sont contextuels
        - une liste cadrée des pages (qui contient forcément celle en cours)
        - une sous-liste de ll, suivant la page en cours
    """
    # controls et calcul de maxPage
    assert nbperpage>1
    assert type(ll)==list
    maxPage=int(math.ceil(float(len(ll))/nbperpage))
    if page!=None:
        assert 1<=page<=maxPage, "nb max de page = %d,page=%d"%(maxPage,page)
    else:
        page=1

    # fabrique de la ligne du "pager navigator"
    lp=range(1,maxPage+1)
    if len(lp)>1:
        idx=lp.index(page)
        off=5
        mi = max(idx-off,0)
        ma = min(mi+(1+off*2),len(lp))
        if idx-(1+off*2)>0:
            mi = min(idx-off,ma-(1+off*2))
        lp=lp[mi:ma]
    else:
        lp=[]

    # retourne les elements affichés dans cette page
    debut = (page-1)*nbperpage
    fin = debut+nbperpage

    # def les touches FIRST/PREV/NEXT/LAST
    first= maxPage>1 and 1 or None
    prev= page>1 and page-1 or None
    next= page<maxPage and page+1 or None
    last = maxPage>1 and maxPage or None

    return (first,prev,next,last),lp,ll[debut:fin]

def pageNavigator(ll,nb,url,page=1):
    assert "%d" in url
    (first,prev,next,last),lp,l=mkPager(ll,nb,page)

    keyPrev,keyNext="",""
    
    lnav=[]
    if prev:
        lnav.append( (url%first, "|<") )
        lnav.append( (url%prev, "<<") )
        keyPrev = url%prev

    for i in lp:
        if i==page:
            lnav.append((None,"<font color='#FFFF00'>%d</font>"%i))
        else:
            lnav.append((url%i,str(i)))

    if next:
        lnav.append( (url%next, ">>"))
        lnav.append( (url%last, ">|"))
        keyNext = url%next

    h=""
    for u,t in lnav:
        if u:
            h+= "<a href='%s'>%s</a>" % (u,t)
        else:
            h+=t
        h+=" "

    return keyPrev,keyNext,h,l

if __name__=="__main__":
    ll=range(5686)
    h,l= pageNavigator(ll,"browse?page=%d",2)
    print h
    print l

